package cn.roadtrip.utilmodule.wechat;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import com.google.gson.Gson;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 小程序工具
 */
@Component
@Slf4j
public class MiniPromUtil {
    @Autowired
    private WeiChatConfig weiChatConfig;

    public static final String WECHAT_MINI_PROM_TOKEN = "wechat_miniprom_token";

    /**
     * 返回登录会话情况<br>
     * {
     * "session_key": "5w/iQe6AH1k4fwMLA0Nu8Q==",
     * "openid": "oUwwe5TxIudtqaNWzLEV-NhqJY1k"
     * "errmsg":"xxxxx"
     * }
     *
     * @param code
     * @return
     */
    public Map<String, String> getLoginSessionByCode(String code) {
        Gson gson = new Gson();
//        log.info(gson.toJson(weiChatConfig));

        String rs = HttpUtil.get("https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code".formatted(
                weiChatConfig.getWchatminiprom().getAppId(),
                weiChatConfig.getWchatminiprom().getSecret(),
                code
        ));
        log.info(rs);
        JSONObject json = new JSONObject(rs);
        return Map.of(
                "session_key", json.getStr("session_key", "")
                , "openid", json.getStr("openid", "")
                , "errmsg", json.getStr("errmsg", "")
        );
    }


    @Autowired
    private RedissonClient redissonClient;//分布式锁
    @Autowired
    private StringRedisTemplate redisTemplate;
    //写一个每隔90分钟执行一次得schedule



    @PostConstruct
    public void freshAccessTokenByPost(){

        log.info("启动任务中刷新token");
        //上锁
        RLock wchattokenlock = redissonClient.getFairLock("wchattokenlock");
        try {
            wchattokenlock.tryLock(14, TimeUnit.SECONDS);

            String rs = HttpUtil.get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s".formatted(
                    weiChatConfig.getWchatminiprom().getAppId(),
                    weiChatConfig.getWchatminiprom().getSecret()
            ));
            JSONObject json = new JSONObject(rs);
            if(!json.getStr("access_token","").equals("")){
                redisTemplate.opsForValue().set(WECHAT_MINI_PROM_TOKEN,json.getStr("access_token",""));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            wchattokenlock.unlock();
        }
    }

    @Scheduled(fixedDelay = 90 * 60 * 1000)
    public void freshAccessToken() {
        try{
            Thread.sleep(3000);//延时3秒
        }catch (Exception e){

        }
        log.info("定时器中刷新token");
        //上锁
        RLock wchattokenlock = redissonClient.getFairLock("wchattokenlock");
        try {
            wchattokenlock.tryLock(14, TimeUnit.SECONDS);

            String rs = HttpUtil.get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s".formatted(
                    weiChatConfig.getWchatminiprom().getAppId(),
                    weiChatConfig.getWchatminiprom().getSecret()
            ));
            JSONObject json = new JSONObject(rs);
            if(!json.getStr("access_token","").equals("")){
                redisTemplate.opsForValue().set(WECHAT_MINI_PROM_TOKEN,json.getStr("access_token",""));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            wchattokenlock.unlock();
        }
    }

    /**
     * 获取电话号码
     * @param code
     * @return
     */
    public String getPhoneNum(String code){
        String rs = HttpUtil.post(
                "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token="
                + redisTemplate.opsForValue().get(WECHAT_MINI_PROM_TOKEN),
                "{\n" +
                        "    \"code\":\""+code+"\"\n" +
                        "}"
        );
        JSONObject obj = new JSONObject(rs);
        try{
            return obj.getJSONObject("phone_info").getStr("purePhoneNumber");
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }
}
